/*
 * FileOpener.java
 *
 * Created on 23. Januar 2008, 19:12
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package de.blitzcoder.collide.engine;

import java.io.File;
import javax.swing.*;
import de.blitzcoder.collide.util.Log;
import de.blitzcoder.collide.Interface;
import de.blitzcoder.collide.gui.BlitzMaxCodeDocument;
import de.blitzcoder.collide.gui.CodeDocument;
import de.blitzcoder.collide.gui.ImageDocument;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.gjt.sp.jedit.buffer.JEditBuffer;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author blitzcoder
 */
public class FileOpener {

    private static HashMap<String, String> fileTypes = new HashMap<String, String>();

    public static void init() {
        try {

            // Create Docbuilder
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();

            // Parse file
            Document doc = builder.parse("filetypes.xml");

            NodeList nodes = doc.getChildNodes().item(1).getChildNodes();
            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                NamedNodeMap map = node.getAttributes();
                if (map != null) {
                    fileTypes.put(map.getNamedItem("ext").getTextContent().toLowerCase(), map.getNamedItem("mode").getTextContent());
                }
            }


        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static Object open(File file) {

        // Check if file is already open
        de.blitzcoder.collide.gui.Document[] docs = Interface.getDocumentManager().getAllDocuments();
        for (de.blitzcoder.collide.gui.Document doc : docs) {
            if (doc.equalsFile(file)) {
                Interface.getDocumentManager().bringToFront(doc);
                return doc;
            }
        }


        if (!file.exists()) {
            JOptionPane.showMessageDialog(Interface.getDialogParent(), "Datei existiert nicht: " + file.getAbsolutePath());
            return null;
        }

        String ext = getExtension(file).toLowerCase();

        String action = fileTypes.get(ext.toLowerCase());

        if (action == null) {
            int ans = JOptionPane.showConfirmDialog(Interface.getDialogParent(), "Kein Programm zum öffnen der Datei gefunden\nEditieren sie die filetypes.xml und fügen sie eine Aktion für das Öffnen von " + ext + "-Dateien hinzu.\n\nSoll die Datei als reiner Text geöffnet werden?",
                    "Datei öffnen", JOptionPane.OK_CANCEL_OPTION);

            if (ans == JOptionPane.OK_OPTION) {

                action = "/text.xml";

            }

        }

        if (action != null) {

            if (action.equalsIgnoreCase("#image")) {

                ImageDocument doc = new ImageDocument(file);
                Interface.getDocumentManager().addDocument(doc);

                return doc;

            } else if (action.equalsIgnoreCase("#executable")) {
                try {
                    RunningProcess process = new RunningProcess(file.getName(), new String[]{file.getAbsolutePath()});
                    Interface.getOutput().addDocument(process);
                } catch (Exception ex) {
                    throw new Error(ex);
                }
            } else if (action.equalsIgnoreCase("#blitzmax")) {

                try {
                    final BlitzMaxCodeDocument doc = new BlitzMaxCodeDocument(file);

                    doc.schedule(new Runnable() {
                        public void run() {
                            Interface.updateSelectBuildFileComboBox();
                        }
                    });

                    Interface.getDocumentManager().addDocument(doc);
                    

                    return doc;
                } catch (Exception ex) {
                    ex.printStackTrace();
                    Log.log("Failed to open " + file.getAbsolutePath() + " (" + ex.getClass().getName() + ")");
                }

            } else if (action.toLowerCase().startsWith("#run")) {
                action = action.substring(4);
                action.replace("%f", file.getAbsolutePath());
                try {
                    return Runtime.getRuntime().exec(action);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                return null;
            } else {

                CodeDocument doc = null;

                String mode = null;
                if (action.startsWith("/")) {
                    mode = "/modes" + action;
                } else {
                    mode = action;
                }

                try {
                    doc = new CodeDocument(file, mode);
                } catch (Exception ex) {
                    Log.log("Failed to open " + file.getAbsolutePath() + " (" + ex.getClass().getName() + ")");
                    return null;
                }

                Interface.getDocumentManager().addDocument(doc);

                return doc;

            }

            return null;
        }

        return null;

    }

    static boolean equalsOneOf(String str, String[] find) {
        for (int i = 0; i < find.length; i++) {
            if (str.equalsIgnoreCase(find[i])) {
                return true;
            }
        }
        return false;
    }

    public static String getExtension(File file) {

        // No extension
        if (file.getName().indexOf(".") == -1) {
            return "";
        }

        return file.getName().substring(file.getName().lastIndexOf(".") + 1, file.getName().length());

    }

    public static void openRecent() {
        File recentFile = new File("recentFiles.dat");

        if (!recentFile.exists()) {
            return;
        }

        try {

            BufferedReader r = new BufferedReader(new FileReader(recentFile));

            while (r.ready()) {

                String fileName = r.readLine();

                boolean buildFile = false;
                if (fileName.startsWith("[build]")) {
                    fileName = fileName.substring(7);
                    buildFile = true;
                }

                Object o = open(new File(fileName));

                if (buildFile && o instanceof CodeDocument) {
                    CodeDocument doc = (CodeDocument) o;
                    final File file = new File(fileName);
                    doc.schedule(new Runnable() {
                        @Override
                        public void run() {
                            Interface.setBuildCode(file.getName());
                        }
                    });
                }

            }

            r.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}
